using System;
using System.Reflection;

namespace Mbs.Messaging
{
    public static class MessageBusExtension
    {

        #region subscriber



        static object GetProperty(this object owner, string propertyName)
        {
            return owner.GetType().GetProperty(propertyName).GetValue(owner, null);
        }



        public static IDisposable Subscribe<T1, T2>(this MessageBus router, ObserverHandler<T1> handler1, ObserverHandler<T2> handler2)
        {
            return router.InternalSubscribe(handler1, handler2);
        }

        public static IDisposable Subscribe<M1, M2, M3>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3)
        {
            return router.InternalSubscribe(handler1, handler2, handler3);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4)
        {
            return router.InternalSubscribe(handler1, handler2, handler3, handler4);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7, ObserverHandler<M8> handler8)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7, ObserverHandler<M8> handler8, ObserverHandler<M9> handler9)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7, ObserverHandler<M8> handler8, ObserverHandler<M9> handler9, ObserverHandler<M10> handler10)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7, ObserverHandler<M8> handler8, ObserverHandler<M9> handler9, ObserverHandler<M10> handler10, ObserverHandler<M11> handler11)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7, ObserverHandler<M8> handler8, ObserverHandler<M9> handler9, ObserverHandler<M10> handler10, ObserverHandler<M11> handler11, ObserverHandler<M12> handler12)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7, ObserverHandler<M8> handler8, ObserverHandler<M9> handler9, ObserverHandler<M10> handler10, ObserverHandler<M11> handler11, ObserverHandler<M12> handler12, ObserverHandler<M13> handler13)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7, ObserverHandler<M8> handler8, ObserverHandler<M9> handler9, ObserverHandler<M10> handler10, ObserverHandler<M11> handler11, ObserverHandler<M12> handler12, ObserverHandler<M13> handler13, ObserverHandler<M14> handler14)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14, M15>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7, ObserverHandler<M8> handler8, ObserverHandler<M9> handler9, ObserverHandler<M10> handler10, ObserverHandler<M11> handler11, ObserverHandler<M12> handler12, ObserverHandler<M13> handler13, ObserverHandler<M14> handler14, ObserverHandler<M15> handler15)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14, handler15);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14, M15, M16>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7, ObserverHandler<M8> handler8, ObserverHandler<M9> handler9, ObserverHandler<M10> handler10, ObserverHandler<M11> handler11, ObserverHandler<M12> handler12, ObserverHandler<M13> handler13, ObserverHandler<M14> handler14, ObserverHandler<M15> handler15, ObserverHandler<M16> handler16)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14, handler15, handler16);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14, M15, M16, M17>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7, ObserverHandler<M8> handler8, ObserverHandler<M9> handler9, ObserverHandler<M10> handler10, ObserverHandler<M11> handler11, ObserverHandler<M12> handler12, ObserverHandler<M13> handler13, ObserverHandler<M14> handler14, ObserverHandler<M15> handler15, ObserverHandler<M16> handler16, ObserverHandler<M17> handler17)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14, handler15, handler16, handler17);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14, M15, M16, M17, M18>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7, ObserverHandler<M8> handler8, ObserverHandler<M9> handler9, ObserverHandler<M10> handler10, ObserverHandler<M11> handler11, ObserverHandler<M12> handler12, ObserverHandler<M13> handler13, ObserverHandler<M14> handler14, ObserverHandler<M15> handler15, ObserverHandler<M16> handler16, ObserverHandler<M17> handler17, ObserverHandler<M18> handler18)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14, handler15, handler16, handler17, handler18);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14, M15, M16, M17, M18, M19>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7, ObserverHandler<M8> handler8, ObserverHandler<M9> handler9, ObserverHandler<M10> handler10, ObserverHandler<M11> handler11, ObserverHandler<M12> handler12, ObserverHandler<M13> handler13, ObserverHandler<M14> handler14, ObserverHandler<M15> handler15, ObserverHandler<M16> handler16, ObserverHandler<M17> handler17, ObserverHandler<M18> handler18, ObserverHandler<M19> handler19)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14, handler15, handler16, handler17, handler18, handler19);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14, M15, M16, M17, M18, M19, M20>(this MessageBus router, ObserverHandler<M1> handler1, ObserverHandler<M2> handler2, ObserverHandler<M3> handler3, ObserverHandler<M4> handler4, ObserverHandler<M5> handler5, ObserverHandler<M6> handler6, ObserverHandler<M7> handler7, ObserverHandler<M8> handler8, ObserverHandler<M9> handler9, ObserverHandler<M10> handler10, ObserverHandler<M11> handler11, ObserverHandler<M12> handler12, ObserverHandler<M13> handler13, ObserverHandler<M14> handler14, ObserverHandler<M15> handler15, ObserverHandler<M16> handler16, ObserverHandler<M17> handler17, ObserverHandler<M18> handler18, ObserverHandler<M19> handler19, ObserverHandler<M20> handler20)
        {
            return router.Subscribe(handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14, handler15, handler16, handler17, handler18, handler19, handler20);
        }


        public static IDisposable Subscribe<T1, T2>(this MessageBus router, string topic1, ObserverHandler<Topic<T1>> handler1, string topic2, ObserverHandler<Topic<T2>> handler2)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2 }, handler1, handler2);
        }

        public static IDisposable Subscribe<M1, M2, M3>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3 }, handler1, handler2, handler3);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4 }, handler1, handler2, handler3, handler4);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5 }, handler1, handler2, handler3, handler4, handler5);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6 }, handler1, handler2, handler3, handler4, handler5, handler6);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7, string topic8, ObserverHandler<Topic<M8>> handler8)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7, topic8 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7, string topic8, ObserverHandler<Topic<M8>> handler8, string topic9, ObserverHandler<Topic<M9>> handler9)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7, topic8, topic9 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7, string topic8, ObserverHandler<Topic<M8>> handler8, string topic9, ObserverHandler<Topic<M9>> handler9, string topic10, ObserverHandler<Topic<M10>> handler10)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7, topic8, topic9, topic10 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7, string topic8, ObserverHandler<Topic<M8>> handler8, string topic9, ObserverHandler<Topic<M9>> handler9, string topic10, ObserverHandler<Topic<M10>> handler10, string topic11, ObserverHandler<Topic<M11>> handler11)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7, topic8, topic9, topic10, topic11 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7, string topic8, ObserverHandler<Topic<M8>> handler8, string topic9, ObserverHandler<Topic<M9>> handler9, string topic10, ObserverHandler<Topic<M10>> handler10, string topic11, ObserverHandler<Topic<M11>> handler11, string topic12, ObserverHandler<Topic<M12>> handler12)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7, topic8, topic9, topic10, topic11, topic12 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7, string topic8, ObserverHandler<Topic<M8>> handler8, string topic9, ObserverHandler<Topic<M9>> handler9, string topic10, ObserverHandler<Topic<M10>> handler10, string topic11, ObserverHandler<Topic<M11>> handler11, string topic12, ObserverHandler<Topic<M12>> handler12, string topic13, ObserverHandler<Topic<M13>> handler13)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7, topic8, topic9, topic10, topic11, topic12, topic13 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7, string topic8, ObserverHandler<Topic<M8>> handler8, string topic9, ObserverHandler<Topic<M9>> handler9, string topic10, ObserverHandler<Topic<M10>> handler10, string topic11, ObserverHandler<Topic<M11>> handler11, string topic12, ObserverHandler<Topic<M12>> handler12, string topic13, ObserverHandler<Topic<M13>> handler13, string topic14, ObserverHandler<Topic<M14>> handler14)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7, topic8, topic9, topic10, topic11, topic12, topic13, topic14 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14, M15>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7, string topic8, ObserverHandler<Topic<M8>> handler8, string topic9, ObserverHandler<Topic<M9>> handler9, string topic10, ObserverHandler<Topic<M10>> handler10, string topic11, ObserverHandler<Topic<M11>> handler11, string topic12, ObserverHandler<Topic<M12>> handler12, string topic13, ObserverHandler<Topic<M13>> handler13, string topic14, ObserverHandler<Topic<M14>> handler14, string topic15, ObserverHandler<Topic<M15>> handler15)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7, topic8, topic9, topic10, topic11, topic12, topic13, topic14, topic15 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14, handler15);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14, M15, M16>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7, string topic8, ObserverHandler<Topic<M8>> handler8, string topic9, ObserverHandler<Topic<M9>> handler9, string topic10, ObserverHandler<Topic<M10>> handler10, string topic11, ObserverHandler<Topic<M11>> handler11, string topic12, ObserverHandler<Topic<M12>> handler12, string topic13, ObserverHandler<Topic<M13>> handler13, string topic14, ObserverHandler<Topic<M14>> handler14, string topic15, ObserverHandler<Topic<M15>> handler15, string topic16, ObserverHandler<Topic<M16>> handler16)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7, topic8, topic9, topic10, topic11, topic12, topic13, topic14, topic15, topic16 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14, handler15, handler16);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14, M15, M16, M17>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7, string topic8, ObserverHandler<Topic<M8>> handler8, string topic9, ObserverHandler<Topic<M9>> handler9, string topic10, ObserverHandler<Topic<M10>> handler10, string topic11, ObserverHandler<Topic<M11>> handler11, string topic12, ObserverHandler<Topic<M12>> handler12, string topic13, ObserverHandler<Topic<M13>> handler13, string topic14, ObserverHandler<Topic<M14>> handler14, string topic15, ObserverHandler<Topic<M15>> handler15, string topic16, ObserverHandler<Topic<M16>> handler16, string topic17, ObserverHandler<Topic<M17>> handler17)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7, topic8, topic9, topic10, topic11, topic12, topic13, topic14, topic15, topic16, topic17 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14, handler15, handler16, handler17);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14, M15, M16, M17, M18>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7, string topic8, ObserverHandler<Topic<M8>> handler8, string topic9, ObserverHandler<Topic<M9>> handler9, string topic10, ObserverHandler<Topic<M10>> handler10, string topic11, ObserverHandler<Topic<M11>> handler11, string topic12, ObserverHandler<Topic<M12>> handler12, string topic13, ObserverHandler<Topic<M13>> handler13, string topic14, ObserverHandler<Topic<M14>> handler14, string topic15, ObserverHandler<Topic<M15>> handler15, string topic16, ObserverHandler<Topic<M16>> handler16, string topic17, ObserverHandler<Topic<M17>> handler17, string topic18, ObserverHandler<Topic<M18>> handler18)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7, topic8, topic9, topic10, topic11, topic12, topic13, topic14, topic15, topic16, topic17, topic18 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14, handler15, handler16, handler17, handler18);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14, M15, M16, M17, M18, M19>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7, string topic8, ObserverHandler<Topic<M8>> handler8, string topic9, ObserverHandler<Topic<M9>> handler9, string topic10, ObserverHandler<Topic<M10>> handler10, string topic11, ObserverHandler<Topic<M11>> handler11, string topic12, ObserverHandler<Topic<M12>> handler12, string topic13, ObserverHandler<Topic<M13>> handler13, string topic14, ObserverHandler<Topic<M14>> handler14, string topic15, ObserverHandler<Topic<M15>> handler15, string topic16, ObserverHandler<Topic<M16>> handler16, string topic17, ObserverHandler<Topic<M17>> handler17, string topic18, ObserverHandler<Topic<M18>> handler18, string topic19, ObserverHandler<Topic<M19>> handler19)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7, topic8, topic9, topic10, topic11, topic12, topic13, topic14, topic15, topic16, topic17, topic18, topic19 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14, handler15, handler16, handler17, handler18, handler19);
        }

        public static IDisposable Subscribe<M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14, M15, M16, M17, M18, M19, M20>(this MessageBus router, string topic1, ObserverHandler<Topic<M1>> handler1, string topic2, ObserverHandler<Topic<M2>> handler2, string topic3, ObserverHandler<Topic<M3>> handler3, string topic4, ObserverHandler<Topic<M4>> handler4, string topic5, ObserverHandler<Topic<M5>> handler5, string topic6, ObserverHandler<Topic<M6>> handler6, string topic7, ObserverHandler<Topic<M7>> handler7, string topic8, ObserverHandler<Topic<M8>> handler8, string topic9, ObserverHandler<Topic<M9>> handler9, string topic10, ObserverHandler<Topic<M10>> handler10, string topic11, ObserverHandler<Topic<M11>> handler11, string topic12, ObserverHandler<Topic<M12>> handler12, string topic13, ObserverHandler<Topic<M13>> handler13, string topic14, ObserverHandler<Topic<M14>> handler14, string topic15, ObserverHandler<Topic<M15>> handler15, string topic16, ObserverHandler<Topic<M16>> handler16, string topic17, ObserverHandler<Topic<M17>> handler17, string topic18, ObserverHandler<Topic<M18>> handler18, string topic19, ObserverHandler<Topic<M19>> handler19, string topic20, ObserverHandler<Topic<M20>> handler20)
        {
            return router.InternalSubscribe(new string[] { topic1, topic2, topic3, topic4, topic5, topic6, topic7, topic8, topic9, topic10, topic11, topic12, topic13, topic14, topic15, topic16, topic17, topic18, topic19, topic20 }, handler1, handler2, handler3, handler4, handler5, handler6, handler7, handler8, handler9, handler10, handler11, handler12, handler13, handler14, handler15, handler16, handler17, handler18, handler19, handler20);
        }
        #endregion

        struct AttachObject
        {
            private IMessageBus MB;
            private string Topic;

            public AttachObject(IMessageBus router, string topic)
            {
                this.MB = router;
                Topic = topic;
            }

            public void Invoke<TEventArgs>(object sender, TEventArgs e)
            {
                MB.Publish(Topic, sender, e);
            }
        }

        internal class _
        {
            public static readonly Type ObserverHandlerType = typeof(ObserverHandler<>);
            public static readonly Type TopicType = typeof(Topic<>);
            public static readonly MethodInfo InvokeMethod = typeof(AttachObject).GetMethod("Invoke");

            public static readonly Type[] AttachArgTypes = new Type[]
		            {
		                 typeof(IMessageBus),
		                 typeof(string),
		                 typeof(object),
		                 typeof(string),
		            };
        }

        public static IDisposable Attach(this IMessageBus router, string topic, object owner, string @event)
        {
            if (string.IsNullOrEmpty(topic))
                throw new ArgumentNullException("topic");

            if (owner == null)
                throw new ArgumentNullException("owner");

            if (string.IsNullOrEmpty(@event))
                throw new ArgumentNullException("event");

            var ei = owner.GetType().GetEvent(@event);
            if (ei == null)
                throw new Exception("invalid event:" + @event + " for " + owner.GetType().Name);

            //TODO:是否支持静态事件
            //if (ei.GetAddMethod().IsStatic ||
            //    ei.GetRemoveMethod().IsStatic)
            //    throw new NotSupportedException("static event does not support!");

            Type eventArgsType = null;
            var ps = ei.EventHandlerType.GetMethod("Invoke").GetParameters();
            if (ps == null || ps.Length == 0)
                throw new NotSupportedException(@event);

            if (ps.Length == 1)
                eventArgsType = ps[0].ParameterType;
            else if (ps.Length == 2)
                eventArgsType = ps[1].ParameterType;

            var closureInvoke = _.InvokeMethod.MakeGenericMethod(eventArgsType);

            var handler = Delegate.CreateDelegate(ei.EventHandlerType, new AttachObject(router, topic), closureInvoke);
            ei.AddEventHandler(owner, handler);
            return new DisposeAction(() => ei.RemoveEventHandler(owner, handler));
        }
    }
}
